package concurrent.threadscheduling;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * 线程调度打印
 * synchronized 关键字实现
 * Created by yzy on 2020-04-08 16:16
 */
public class MultiThreadPrintSynch {

    private static volatile String PRINT_FLAG = "A";
    private static volatile int PRINT_NUM = 0;
    private static final int TOTAL_NUM = 20;
    private static CyclicBarrier cb = new CyclicBarrier(3);


    public static void main(String[] args) throws InterruptedException {
        Object lock = new Object();
        PrintThread p1 = new PrintThread("A","B",lock);
        PrintThread p2 = new PrintThread("B","C",lock);
        PrintThread p3 = new PrintThread("C","A",lock);

        p1.start();
        p3.start();
        p2.start();

    }

    public static class PrintThread extends Thread{
        private String threadFlag;
        private String nextFlag;
        private Object lock;

        public PrintThread(String threadFlag, String nextFlag, Object lock) {
            this.threadFlag = threadFlag;
            this.nextFlag = nextFlag;
            this.lock = lock;
        }

        @Override
        public void run() {
            System.out.println(threadFlag + "is ready...");
            try {
                cb.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            System.out.println(threadFlag + "is start...");

            while(PRINT_NUM <= TOTAL_NUM){
                synchronized (lock){
                    while(threadFlag != PRINT_FLAG){
                        // 这里是为了终止程序
                        if(PRINT_NUM > TOTAL_NUM) return;

                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                    // 这里是为了防止多打印
                    if(PRINT_NUM > TOTAL_NUM) return;
                    System.out.println(threadFlag + "----" + PRINT_NUM);
                    PRINT_FLAG = nextFlag;
                    PRINT_NUM++;
                    lock.notifyAll();
                }
            }

        }
    }
}
